package com.hlm.testredis.util;

import lombok.Data;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @program:test-redis
 * @description:数组的实体类
 * @author: xinY
 * @create:2020-07-28 17:46
 **/

public class MagicArray {
    private double[] metas;
    private double variance;
    private double average;
    private double min;
    private double max;
    private int groupNum;
    private double interval;
    private double groupUpLimit;
    private double groupDownLimit;
    private double groupInterval;

    public MagicArray(){

    }

    public MagicArray(double[] metas) {
        this.metas = metas;
    }

    public MagicArray(double[] metas, int groupNum, double interval) {
        this.metas = metas;
        this.groupNum = groupNum;
        this.interval = interval;
    }

    public double[] getMetas() {
        return metas;
    }

    public void setMetas(double[] metas) {
        this.metas = metas;
    }

    public double getVariance() {
        double sumCha = 0 ;
        for(int i = 0 ; i < this.metas.length ; i ++){
            double cha = this.metas[i]-getAverage();
            sumCha = sumCha + (cha * cha);
        }
        this.variance =sumCha/this.metas.length;
        return variance;
    }

    public double getAverage() {
        double sum = 0 ;
        for(int i = 0 ; i < this.metas.length ; i ++){
            sum = sum + this.metas[i];
        }
        this.average= sum/this.metas.length;
        return average;

    }
    public double getMin() {
        Arrays.sort(this.metas);
        this.min = metas[0];
        return min;
    }

    public double getMax() {
        Arrays.sort(this.metas);
        this.max = metas[metas.length-1];
        return max;
    }

    public int getGroupNum() {
        return groupNum;
    }

    public void setGroupNum(int groupNum) {
        this.groupNum = groupNum;
    }

    public double getInterval() {
        return interval;
    }

    public void setInterval(double interval) {
        this.interval = interval;
    }

    public double getGroupUpLimit() {
        this.groupUpLimit = getAverage() + interval * Math.sqrt(getVariance());
        return  groupUpLimit;
    }

    public double getGroupDownLimit() {
        this.groupDownLimit = getAverage() - interval * Math.sqrt(getVariance());
        return groupDownLimit;
    }

    public double getGroupInterval() {
        this.groupInterval = (getGroupUpLimit() - getGroupDownLimit())/(this.groupNum -1);
        return groupInterval;
    }

    /**
     * 用概率密度函数分布
     * @param metas
     * @return   x，y 坐标
     */
    public Map<Double,Double> distribute(double[] metas){
        Map<Double,Double> resultMap = new HashMap<>();
        Arrays.sort(metas);
        double avg = getAverage();
//        概率密度函数---------------------------------------------------------------
        for(int i = 0 ; i < metas.length ; i ++){
            double left = 1.0/Math.sqrt(2 * Math.PI * getVariance());
            double right = Math.exp(-((metas[i]-avg) * (metas[i]-avg)/(2 * getVariance())));
            double midu = left * right ;
//            System.out.println("x:"+ metas[i] + "y:" + midu);
            resultMap.put(metas[i],midu);
        }
        return resultMap;
    }

    /**
     * 分组频次
     * @return
     */
    public  Map<Double,Integer> countPerGroup(){
        Map<Double,Integer> resultMap = new HashMap<>();
        Arrays.sort(metas);
        double downLimitGroup = getGroupDownLimit();
        double upLimitGroup = getGroupUpLimit();
        double groupInterval = getGroupInterval();
        int countPerGroup = 0 ;
        for(int i = 0 ; i < metas.length ; i ++){
            if(metas[i] <= downLimitGroup && downLimitGroup <= upLimitGroup){
                countPerGroup = countPerGroup +1 ;
            }else{
                System.out.println("x:"+downLimitGroup + "====y:"+countPerGroup);
                resultMap.put(downLimitGroup,countPerGroup);
                downLimitGroup = downLimitGroup + groupInterval;
                // 此时 有一个在夹缝中的数据 ，把他加进去
                countPerGroup =    1;
                // 最后的一个组里面没有东西  （有14个组，应该有15个组）
            }
        }
        return  resultMap;
    }
}
